using Engine.FileFormats3D;
using Engine.FileFormats3D.WR2TerrainLoader;
using Scenario_Editor.RoadBuilder;
using Scenario_Editor.Tools;
using Scenario_Editor.Tracks;
using SharpDX.Direct3D11;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Windows.Forms;
using Tools;
using WR2Streetformat.WR2TrafficFiles;

namespace Scenario_Editor.Exporter
{
    internal partial class ExportWindow : Form
    {
        #region Private Fields

        private DirectoryInfo projectDirectory;
        private DirectoryInfo scenarioDirectory;
        private ScenarioFile scenarioFile;
        private DirectoryInfo wrRootDirectory;

        #endregion Private Fields

        #region Public Constructors

        public ExportWindow(string WRRoot, RoadV2 RoadMesh, Terrain TerrainForExport, Tools.ObjectPlacerControl objects, List<Track> tracks, string[] SurfaceNames, Device device)
        {
            InitializeComponent();
            UpdateFoldernames(WRRoot);
            //roadMesh = RoadMesh;
            //terrain = TerrainForExport;
            //this.objects = objects;
            //surfaceNames = SurfaceNames;
            //this.tracks = tracks;
            //this.comboBox_scale.SelectedIndex = 1;
        }

        public ExportWindow()
        {
            InitializeComponent();
        }

        #endregion Public Constructors

        #region Private Delegates

        private delegate void SetTextCallback(string newText);

        #endregion Private Delegates

        #region Public Methods

        public void ExportScenario(ScenarioFile scenarioFile, string WRRoot)
        {
            UpdateFoldernames(WRRoot);
            this.scenarioFile = scenarioFile;
        }

        #endregion Public Methods

        #region Private Methods

        private void AppendTextToLog(string text)
        {
            // InvokeRequired required compares the thread ID of the
            // calling thread to the thread ID of the creating thread.
            // If these threads are different, it returns true.
            if (this.richTextBox.InvokeRequired)
            {
                SetTextCallback d = new SetTextCallback(AppendTextToLog);
                //this.richTextBox.Invoke(d.Invoke(d, new object[] { text });
                this.richTextBox.Invoke(d, new object[] { text });
            }
            else
            {
                richTextBox.AppendText(text);
            }
        }

        private void button_NewScenery_Click(object sender, EventArgs e)
        {
            NewScenario newScenarioDialog = new NewScenario();
            if (newScenarioDialog.ShowDialog(this) == DialogResult.OK)
            {
                Directory.CreateDirectory(scenarioDirectory + "\\" + newScenarioDialog.GetScenarioName());
                UpdateFoldernames(wrRootDirectory.FullName);
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            scenarioDirectory = new DirectoryInfo(wrRootDirectory.FullName);
            if (scenarioDirectory.Exists)
            {
                folderBrowserDialog_WRRoot.SelectedPath = scenarioDirectory.FullName;
            }
            if (folderBrowserDialog_WRRoot.ShowDialog(this) == DialogResult.OK)
            {
                UpdateFoldernames(folderBrowserDialog_WRRoot.SelectedPath);
            }
        }

        private void buttonExport_Click(object sender, EventArgs e)
        {
            Button button = (Button)sender;
            button.Enabled = false;

            // Set focus to the richtextbox to get the scrollbars to the coursor.
            this.richTextBox.ScrollToCaret();
            this.richTextBox.Focus();

            this.scenarioFile.statusExportChanged += new ScenarioFile.StatusExportChanged(OnStatusExportChange);
            Wr2Scenario.exportStatus += new Wr2Scenario.ExportStatus(OnStatusExportChange);

            if (projectDirectory != null && projectDirectory.Exists)
            {
                Stopwatch sw = new Stopwatch();
                sw.Start();
                // Export Scenery
                if (checkBox_ExportScenario.Checked)
                {
                    ScenarioFile.ExportOptions exportOptions = (this.radioButton_CreateNew.Checked) ? ScenarioFile.ExportOptions.CreateNew : ScenarioFile.ExportOptions.Update;

                    if (this.checkBox_ExportObjects.Checked)
                        exportOptions = exportOptions | ScenarioFile.ExportOptions.ExportObjects;

                    this.scenarioFile.ExportToWR2Scenario(projectDirectory, exportOptions);
                }

                if (checkBox_CopyTextures.Checked)
                {
                    CopyUsedTextures();
                }

                // Export Tracks
                if (checkBox_ExportTracks.Checked)
                {
                    try
                    {
                        for (int i = 0; i < this.scenarioFile.TrackManager.Tracks.Count; i++)
                        {
                            if (false)
                            {
                                // Export LWO-File
                                string filename = projectDirectory.FullName + "\\track_" + ((int)(i + 1)).ToString() + ".lwo";

                                try
                                {
                                    this.scenarioFile.TrackManager.Tracks[i].ExportToLWO(filename, 0.10f);
                                    richTextBox.AppendText("\nSaved to LWO file: \"" + filename + "\"\n");
                                }
                                catch
                                {
                                    richTextBox.AppendText(string.Format("\nError while writing Track_{0}", i));
                                }
                            }
                            else
                            {
                                //loopState.
                                string filename = projectDirectory.FullName + "\\V1\\Tracks\\" + projectDirectory.Name + "_" + ((int)(i + 1)).ToString().PadLeft(2, '0') + ".trk";
                                this.scenarioFile.TrackManager.Tracks[i].ExportToWr2Track(filename, (ITerrain)scenarioFile.Terrain, this.checkBox_CreateIdealline.Checked);

                                Application.DoEvents();
                                AppendTextToLog("\nTrack Saved: \"" + filename + "\"" /*+ ((float)sw.Elapsed.TotalSeconds).ToString() */+ "\n");
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show("Error track writing...");
                    }
                }

                if (checkBox_traffic.Checked)
                {
                    CreateTrafficFile(this.scenarioFile.RoadManager, wrRootDirectory + "\\Traffic\\Streets\\" + projectDirectory.Name + ".str");
                }
                sw.Stop();
                try
                {
                    richTextBox.AppendText("\n\n" + ((float)sw.Elapsed.TotalSeconds).ToString() + " seconds elapsed\n\n");
                }
                catch
                {
                }
            }
            else
            {
                MessageBox.Show("Please select a Scenery Folder");
            }

            // Remove Update Events
            this.scenarioFile.statusExportChanged -= OnStatusExportChange;
            Wr2Scenario.exportStatus -= OnStatusExportChange;
            button.Enabled = true;
            if (projectDirectory != null && projectDirectory.Exists)
            {
                StKit2Workfile.Export(projectDirectory.FullName + "\\V1\\" + projectDirectory.Name + " WorkFile.wrk", this.scenarioFile.TextureSetupWindow.TextureProperties, this.scenarioFile.MaterialManager, QADFile.FromFile(projectDirectory.FullName + "\\V1\\" + projectDirectory.Name + ".qad"));
            }
        }

        private void checkBox_ExportTracks_CheckedChanged(object sender, EventArgs e)
        {
            this.checkBox_CreateIdealline.Enabled = (this.checkBox_ExportTracks.Checked) ? true : false;
        }

        private void comboBox_listedSceberies_SelectedIndexChanged(object sender, EventArgs e)
        {
            projectDirectory = new DirectoryInfo(scenarioDirectory.FullName + "\\" + comboBox_listedSceberies.SelectedItem.ToString());
        }

        private void CopyUsedTextures()
        {
            if (this.scenarioFile.MaterialManager.GetNumberOfMaterials() > 0)
            {
                List<string> textureNames = new List<string>();
                for (int i = 0; i < this.scenarioFile.MaterialManager.GetNumberOfMaterials(); i++)
                {
                    Engine.Graphics.Material item = this.scenarioFile.MaterialManager.GetMaterial(i);

                    if (!textureNames.Contains(item.TextureName1))
                        textureNames.Add(item.TextureName1);
                    if (!textureNames.Contains(item.TextureName2))
                        textureNames.Add(item.TextureName2);
                    if (!textureNames.Contains(item.TextureName3))
                        textureNames.Add(item.TextureName3);
                }

                foreach (string surfacename in textureNames)
                {
                    if (!Directory.Exists(projectDirectory + "\\V1\\Textures\\"))
                    {
                        Directory.CreateDirectory(projectDirectory + "\\V1\\Textures\\");
                    }
                    File.Copy(Application.StartupPath + "\\Texture\\" + surfacename + ".ptx", projectDirectory + "\\V1\\Textures\\" + surfacename + ".ptx", true);
                }
            }
        }

        private void CreateTrafficFile(RoadManager roadMesh, string filename)
        {
            WR2TrafficFile wr2TrafficFile = new WR2TrafficFile(roadMesh);
            wr2TrafficFile.Save(filename);
        }

        private void OnStatusExportChange(object sender, EventArgs e)
        {
            this.richTextBox.AppendText((string)sender);
        }

        private void UpdateFoldernames(string WRRootDirectory)
        {
            wrRootDirectory = new DirectoryInfo(WRRootDirectory);
            textBox_WRroot.Text = wrRootDirectory.FullName;
            scenarioDirectory = new DirectoryInfo(wrRootDirectory.FullName + "\\Scenarios");

            //DirectoryInfo scenerieInfo = new DirectoryInfo(scenarioDirectory);
            if (scenarioDirectory.Exists)
            {
                button_NewScenery.Enabled = true;
                DirectoryInfo[] directoriesScenarios = scenarioDirectory.GetDirectories();
                comboBox_listedSceberies.Items.Clear();
                foreach (DirectoryInfo dir in directoriesScenarios)
                {
                    comboBox_listedSceberies.Items.Add(dir.Name);
                }
            }
            else
            {
                projectDirectory = null;
                comboBox_listedSceberies.Items.Clear();
                comboBox_listedSceberies.Text = string.Empty;
                button_NewScenery.Enabled = false;
            }
        }

        #endregion Private Methods
    }
}